{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Use case proposed in [issue #78](https://github.com/bsorrentino/langgraph4j/issues/78) by [ikwattro](https://github.com/ikwattro)\n",
    "\n",
    "## How to Reset memory thread "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "var userHomeDir = System.getProperty(\"user.home\");\n",
    "var localRespoUrl = \"file://\" + userHomeDir + \"/.m2/repository/\";\n",
    "var langchain4jVersion = \"1.0.1\";\n",
    "var langchain4jbeta = \"1.0.1-beta6\";\n",
    "var langgraph4jVersion = \"1.6-SNAPSHOT\";"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%dependency /add-repo local \\{localRespoUrl} release|never snapshot|always\n",
    "// %dependency /list-repos\n",
    "%dependency /add org.slf4j:slf4j-jdk14:2.0.9\n",
    "%dependency /add org.bsc.langgraph4j:langgraph4j-core:\\{langgraph4jVersion}\n",
    "%dependency /add org.bsc.langgraph4j:langgraph4j-langchain4j:\\{langgraph4jVersion}\n",
    "%dependency /add org.bsc.langgraph4j:langgraph4j-agent-executor:\\{langgraph4jVersion}\n",
    "%dependency /add dev.langchain4j:langchain4j:\\{langchain4jVersion}\n",
    "%dependency /add dev.langchain4j:langchain4j-ollama:\\{langchain4jbeta}\n",
    "\n",
    "%dependency /resolve"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Initialize Logger**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "try( var file = new java.io.FileInputStream(\"./logging.properties\")) {\n",
    "    java.util.logging.LogManager.getLogManager().readConfiguration( file );\n",
    "}\n",
    "\n",
    "var log = org.slf4j.LoggerFactory.getLogger(\"AdaptiveRag\");\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.bsc.langgraph4j.state.AgentState;\n",
    "import org.bsc.langgraph4j.state.Channel;\n",
    "import java.util.Optional;\n",
    "\n",
    "public class State extends AgentState {\n",
    "    static Map<String, Channel<?>> SCHEMA = Map.of();\n",
    "    \n",
    "    public State(Map<String,Object> initData) {\n",
    "        super(initData);\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import dev.langchain4j.model.ollama.OllamaChatModel;\n",
    "import dev.langchain4j.model.chat.Capability;\n",
    "\n",
    "var chatLanguageModel = OllamaChatModel.builder()\n",
    "            .modelName(\"llama3.1\")\n",
    "            .baseUrl(\"http://localhost:11434\")\n",
    "            //.supportedCapabilities( Capability.RESPONSE_FORMAT_JSON_SCHEMA )\n",
    "            .temperature(0.0d)\n",
    "            .logRequests(true)\n",
    "            .logResponses(true)\n",
    "            .build();\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.bsc.langgraph4j.action.NodeActionWithConfig;\n",
    "import org.bsc.langgraph4j.RunnableConfig;\n",
    "import dev.langchain4j.service.AiServices;\n",
    "import dev.langchain4j.model.chat.ChatModel;\n",
    "import dev.langchain4j.memory.chat.MessageWindowChatMemory;\n",
    "import dev.langchain4j.service.MemoryId;\n",
    "import dev.langchain4j.service.UserMessage;\n",
    "\n",
    "class TestAction implements NodeActionWithConfig<State> {\n",
    "\n",
    "    private final TestAssistant testAssistant;\n",
    "\n",
    "    public TestAction(ChatModel chatModel) {\n",
    "        this.testAssistant = AiServices.builder(TestAssistant.class)\n",
    "                .chatModel(chatModel)\n",
    "                .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(20))\n",
    "                .build();\n",
    "    }\n",
    "\n",
    "    @Override\n",
    "    public Map<String, Object> apply(State state, RunnableConfig runnableConfig) throws Exception {\n",
    "        var conversation = state.<String>value(\"conversation\")\n",
    "                                .orElseThrow(() -> new IllegalStateException(\"No conversation found in state\"));\n",
    "\n",
    "        var threadId = runnableConfig.threadId().orElse( \"unknown\" );\n",
    "\n",
    "        return Map.of(\"response\", testAssistant.test( threadId, conversation));\n",
    "    }\n",
    "\n",
    "    public interface TestAssistant {\n",
    "        String test(@MemoryId String memoryId, @UserMessage String query);\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.bsc.langgraph4j.StateGraph;\n",
    "import static org.bsc.langgraph4j.action.AsyncNodeActionWithConfig.node_async;\n",
    "import static org.bsc.langgraph4j.StateGraph.START;\n",
    "import static org.bsc.langgraph4j.StateGraph.END;\n",
    "\n",
    "var testAction = new TestAction(chatLanguageModel);\n",
    "\n",
    "var workflow =  new StateGraph<>(State.SCHEMA, State::new)\n",
    "            .addNode(\"agent\", node_async(testAction))\n",
    "            .addEdge(START, \"agent\")\n",
    "            .addEdge(\"agent\", END);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "START \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{response=Nice to meet you, Chris! Is there something I can help you with or would you like to chat?, conversation=Hi, my name is Chris}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "START \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{response=Your name is Chris. We just established that a minute ago!, conversation=what's my name ?}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "START \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{response=I don't have any information about your name. This is the beginning of our conversation, and I'm a large language model, I don't retain any personal data or context from previous conversations. If you'd like to share your name with me, I can use it in our conversation!, conversation=What's my name ?}\n"
     ]
    }
   ],
   "source": [
    "import org.bsc.langgraph4j.checkpoint.MemorySaver;\n",
    "import org.bsc.langgraph4j.CompileConfig;\n",
    "import org.bsc.langgraph4j.RunnableConfig;\n",
    "\n",
    "var memory = new MemorySaver();\n",
    "var compileConfig = CompileConfig.builder()\n",
    "        .checkpointSaver(memory)\n",
    "        .build();\n",
    "\n",
    "var runnableConfig1 = RunnableConfig.builder()\n",
    "        .threadId(\"conversation-num-1\")\n",
    "        .build();\n",
    "var runnableConfig2 = RunnableConfig.builder()\n",
    "        .threadId(\"conversation-num-2\")\n",
    "        .build();\n",
    "\n",
    "var app = workflow.compile(compileConfig);\n",
    "\n",
    "app.invoke( Map.of(\"conversation\", \"Hi, my name is Chris\"), runnableConfig1 )\n",
    "        .map( r -> r.data() )\n",
    "        .ifPresent( System.out::println  );\n",
    "\n",
    "app.invoke( Map.of(\"conversation\", \"what's my name ?\"), runnableConfig1 )\n",
    "        .map( r -> r.data() )\n",
    "        .ifPresent( System.out::println );\n",
    "\n",
    "app.invoke( Map.of(\"conversation\", \"What's my name ?\"), runnableConfig2 )\n",
    "        .map( r -> r.data() )\n",
    "        .ifPresent( System.out::println );\n",
    "\n",
    "    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java (rjk 2.2.0)",
   "language": "java",
   "name": "rapaio-jupyter-kernel"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "java",
   "nbconvert_exporter": "script",
   "pygments_lexer": "java",
   "version": "22.0.2+9-70"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
